package io.gitee.caoxiaoyu97.log4j.defender.message.log;

import io.gitee.caoxiaoyu97.log4j.defender.properties.DefenderKeyProperties;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.util.StringUtils;

public class RegexKeyDefender extends AbstractLogDefender<Pattern> {
    protected Set<String> originKeyList;

    public RegexKeyDefender(DefenderKeyProperties properties) {
        super(properties);
    }


    protected Set<Pattern> transformToMatcher(DefenderKeyProperties properties) {
        this.originKeyList = readKeysFromProperty(properties.getKeys(), properties.getSplitter());
        Set<Pattern> patterns = new HashSet<>();
        if (this.originKeyList.size() == 0) {
            return patterns;
        }
        StringBuilder wholePattern = new StringBuilder("(\"|<)?\\b((");
        AtomicBoolean first = new AtomicBoolean(true);
        for (String key : this.originKeyList) {
            if (!StringUtils.isEmpty(key.trim())) {
                if (first.compareAndSet(true, false)) {
                    wholePattern.append(key);
                    continue;
                }
                wholePattern.append("|").append(key);
            }
        }

        wholePattern.append(")(>|\":\"|=)\\s*)([^\",<}{]+)([\"]|$|(?=[<}{,]))");
        patterns.add(Pattern.compile(wholePattern.toString()));
        return patterns;
    }


    public StringBuilder doDesensitize(StringBuilder inputOrigin) {
        StringBuilder input = inputOrigin;
        String tmpMsg = "";
        for (Pattern pattern : this.toMatchKeys) {
            Matcher matcher = pattern.matcher(input);

            while (matcher.find()) {
                tmpMsg = matcher.group();
                tmpMsg = this.strategy.doMark(tmpMsg);
                input = input.replace(matcher.start(), matcher.end(), tmpMsg);
                matcher = pattern.matcher(input);
            }
        }
        return input;
    }


    protected boolean isQuickMatch(StringBuilder input) {
        return this.originKeyList.stream().anyMatch(it -> (input.indexOf(it) > -1));
    }
}
